package com.yb.guigu.pick.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yb.guigu.pick.auth.bean.dto.request.SysUserAddInfo;
import com.yb.guigu.pick.auth.bean.dto.response.SysRoleDTO;
import com.yb.guigu.pick.auth.bean.dto.response.SysUserCreateDTO;
import com.yb.guigu.pick.auth.bean.dto.response.SysUserDTO;
import com.yb.guigu.pick.auth.bean.vo.request.*;
import com.yb.guigu.pick.auth.entity.*;
import com.yb.guigu.pick.auth.mapper.SysPermissionMapper;
import com.yb.guigu.pick.auth.mapper.SysRolePermissionMapper;
import com.yb.guigu.pick.auth.mapper.SysUserMapper;
import com.yb.guigu.pick.auth.mapper.SysUserRoleMapper;
import com.yb.guigu.pick.auth.service.ISysUserService;
import com.yb.guigu.pick.cache.manager.api.GuiguPickStringCacheManager;
import com.yb.guigu.pick.security.bean.GuiguPickGrantedAuthority;
import com.yb.guigu.pick.security.bean.GuiguPickUser;
import com.yb.guigu.pick.security.encoder.GuiguPasswordEncoder;
import com.yb.guigu.pick.security.util.SecurityUtil;
import com.yb.guigu.pick.core.bean.GuiguResult;
import com.yb.guigu.pick.core.constant.RedisKeyConstant;
import com.yb.guigu.pick.core.publisher.GuiguPickEventPublisher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 姚兵
 * @since 2023-05-30
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    SysUserRoleMapper sysUserRoleMapper;


    @Autowired
    SysRolePermissionMapper sysRolePermissionMapper;


    @Autowired
    SysPermissionMapper sysPermissionMapper;


    @Autowired
    GuiguPickStringCacheManager stringCacheManager;


    @Autowired
    GuiguPickEventPublisher guiguPickEventPublisher;


    @Override
    public GuiguResult listUserDTO() {
        List<SysUser> list = this.list();
        List<SysUserDTO> userDTOS = list.stream().map(item->{
            SysUserDTO sysUserDTO=new SysUserDTO();
            BeanUtils.copyProperties(item,sysUserDTO);
            return sysUserDTO;
        }).collect(Collectors.toList());
        return GuiguResult.success(userDTOS);
    }

    @Autowired
    GuiguPasswordEncoder guiguPasswordEncoder;
    @Override
    public GuiguResult create() {
        List<SysUser> sysUsers=new ArrayList<>();
        String password = guiguPasswordEncoder.encode("123456");
        for(int i=0;i<100;i++){
            SysUser sysUser = new SysUser();
            sysUser.setUserId(2000+i    );
            sysUser.setUsername("user"+i);
            sysUser.setRealname("realname"+i);
            sysUser.setEmail("32210833"+i+"@qq.com");
            sysUser.setPhone("15212142"+i);
            sysUser.setEncryptedType("1");
            sysUser.setCreateTime(LocalDateTime.now());
            sysUser.setPassword(password);
            sysUsers.add(sysUser);
        }
        this.saveBatch(sysUsers);
        return GuiguResult.success();
    }

    @Override
    public GuiguResult listUserDTO(GuiguPage<SysUserConditionVo> page) {


        //构造分页参数
        Page<SysUser> p = new Page<>(page.getCurrent(),page.getSize());

        //构造查询条件
        SysUserConditionVo condition = page.getCondition();

        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();

        String username = condition.getUsername();
        String realname = condition.getRealname();
        String email = condition.getEmail();
        String phone = condition.getPhone();

        if(StringUtils.hasText(username)){
            queryWrapper.like(SysUser::getUsername, username.trim());
        }

        if(StringUtils.hasLength(realname)){
            queryWrapper.like(SysUser::getRealname, realname.trim());

        }

        if(StringUtils.hasText(email)){
            queryWrapper.eq(SysUser::getEmail, email.trim());
        }

        if(StringUtils.hasText(phone)){
            queryWrapper.eq(SysUser::getPhone, phone.trim());
        }

        if(Objects.nonNull(condition.getUserId())){
            queryWrapper.eq(SysUser::getUserId,condition.getUserId());
        }

        queryWrapper.orderByDesc(SysUser::getId);

        //查询分页结果
        Page<SysUser> userPage = this.page(p,queryWrapper);

        //封装返回结果
        List<SysUser> records = userPage.getRecords();
        List<SysUserDTO> result = records.stream().map(item -> {
            SysUserDTO sysUserDTO = new SysUserDTO();
            BeanUtils.copyProperties(item, sysUserDTO);
            return sysUserDTO;
        }).collect(Collectors.toList());
        Page<SysUserDTO> resultPage = new Page<>();
        resultPage.setRecords(result);
        resultPage.setTotal(userPage.getTotal());
        resultPage.setPages(userPage.getPages());
        return GuiguResult.success(resultPage);
    }

    @Override
    public GuiguResult createUser(SysUserCreateVo createVo) {

        String key= RedisKeyConstant.GUIGU_PICK_USERID_INCREMENT;

        Long userId=stringCacheManager.increment(key);

        SysUser sysUser=new SysUser();

        BeanUtils.copyProperties(createVo,sysUser);

        sysUser.setPassword(guiguPasswordEncoder.encode(sysUser.getEncryptedType(),sysUser.getPassword()));

        sysUser.setUserId(userId.intValue());

        this.save(sysUser);

        guiguPickEventPublisher.publish(this,new SysUserAddInfo(sysUser));

        SysUserCreateDTO createDTO=new SysUserCreateDTO();

        BeanUtils.copyProperties(sysUser,createDTO);

        return GuiguResult.success(createDTO);
    }

    @Override
    public GuiguResult updateUser(SysUserUpdateVo updateVo) {
        Integer id = updateVo.getId();
        Integer userId = updateVo.getUserId();

        SysUser sysUser=new SysUser();
        BeanUtils.copyProperties(updateVo,sysUser);
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getId,id)
                .eq(SysUser::getUserId,userId);
        sysUser.setUpdateTime(LocalDateTime.now());
        this.update(sysUser,wrapper);
        return GuiguResult.success("更新成功");
    }

    @Override
    public GuiguResult modifyPassword(ModifyPasswordRequest modifyPasswordRequest) {
        GuiguPickUser userInfo = SecurityUtil.getUserInfo();

        Integer userId = userInfo.getUserId();
        Integer modifyUserId = modifyPasswordRequest.getUserId();
        
        if(!userId.equals(modifyUserId)){
            return GuiguResult.error("不是本人操作,不允许修改密码");
        }

        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);

        String encodePassword = guiguPasswordEncoder.encode(modifyPasswordRequest.getEncryptedType(), modifyPasswordRequest.getPassword());

        sysUser.setPassword(encodePassword);
        sysUser.setEncryptedType(modifyPasswordRequest.getEncryptedType()) ;

        this.update(sysUser,new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserId,userId));

        return GuiguResult.success();
    }

    @Override
    public GuiguResult userRole(Integer userId) {
        List<SysRole> roleList = this.baseMapper.userRole(userId);

        List<SysRoleDTO> roleDTOS = roleList.stream().map(item -> {
            SysRoleDTO sysRoleDTO = new SysRoleDTO();
            BeanUtils.copyProperties(item, sysRoleDTO);
            return sysRoleDTO;
        }).collect(Collectors.toList());

        return GuiguResult.success(roleDTOS);
    }
}
